package ar.republicagroup.gestion.dao.jpa;

import ar.republicagroup.gestion.dao.ClienteDAO;
import ar.republicagroup.gestion.entities.BolsaCheque;
import ar.republicagroup.gestion.entities.Cheque;
import ar.republicagroup.gestion.entities.Cliente;
import ar.republicagroup.gestion.util.JComboBoxModel;
import ar.republicagroup.gestion.util.JPAUtil;
import ar.republicagroup.gestion.util.UserSession;
import ar.republicagroup.gestion.util.messages.UIMessages;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.swing.DefaultComboBoxModel;
import org.apache.log4j.Logger;

public class ClienteDAOImplJPA implements ClienteDAO{
	
        private static Logger            log = Logger.getLogger(ClienteDAOImplJPA.class);
	private EntityManager		 em;
	
	
	public ClienteDAOImplJPA(){
		this.em = JPAUtil.getEntityManager();
	}
	

	@Override
	public List<Cliente> findEntities() {
		TypedQuery<Cliente> query = em.createQuery("select c From Cliente c WHERE c.estado = 1",Cliente.class);
		return query.getResultList();
	}

	@Override
	public String insert(Cliente beanCliente) {
                if(!em.isOpen()) { em = JPAUtil.getEntityManager(); }
                
                log.info(UserSession.getInstance().getUser_name()+"--->"+" Registrando nuevo cliente : "+beanCliente.getNombre());
                String mensaje = null;
		
		try{
			em.getTransaction().begin();
			em.persist(beanCliente);
			em.getTransaction().commit();
			mensaje = "Se registró el cliente";
		}catch(Exception ex){
                        log.error("Error al registrar cliente",ex);
			em.getTransaction().rollback();
                }
	
                finally{
                    return mensaje;
                }
	}

	@Override
	public String update(Cliente beanCliente) {
		
                log.info(UserSession.getInstance().getUser_name()+"--->"+"  Actualizando datos de cliente "+beanCliente.getId());
                String mensaje = null;
		
                if(!em.isOpen()) { em = JPAUtil.getEntityManager(); }
                
		/* BUSCAMOS EL CLIENTE PARA SETEARLE LOS DATOS */
                Cliente persistCliente 		= em.find(Cliente.class, beanCliente.getId());
                
                /* SETEAMOS LOS DATOS MODIFICADOS en persistCliente*/
		persistCliente.setNombre(beanCliente.getNombre());
		persistCliente.setTelefono(beanCliente.getTelefono());
		persistCliente.setDireccion(beanCliente.getDireccion());
		persistCliente.setEmail(beanCliente.getEmail());
		persistCliente.setCelular(beanCliente.getCelular());
		persistCliente.setComisionBa(beanCliente.getComisionBa());
		persistCliente.setComisionInterior(beanCliente.getComisionInterior());
                persistCliente.setComisionDeposito(beanCliente.getComisionDeposito());
		
                /* HACEMOS UN MERGE DE persistCliente*/
                        try
                        {
				em.getTransaction().begin();
				em.merge(persistCliente);	
				em.getTransaction().commit();
				mensaje = UIMessages.getInfoMessage("onCompleteUpdate");
                                log.info("Actualización de cliente correcta!");
			}catch(Exception ex){
				em.getTransaction().rollback();
				log.error("Error al actualizar cliente -->"+ex.getMessage(),ex);
			}
		
		return mensaje;
	}

	@Override
	public Cliente get(Integer idcliente) {
		return em.find (Cliente.class, idcliente);
        }

	@Override
	public String delete(Integer idcliente) {
                log.info(UserSession.getInstance().getUser_name()+" "+"eliminando cliente");
                log.info("Eliminando cliente : "+idcliente);
		String mensaje = null;
		/* BUSCAMOS EL CLIENTE PARA SETEARLE LOS DATOS */
		Cliente deleteCliente 		= em.find(Cliente.class, idcliente);
		deleteCliente.setEstado(0);		//<--- Eliminaci�n l�gica , estado = 0
                
                for(BolsaCheque bolsaCliente : deleteCliente.getBolsaChequeList()){
                    bolsaCliente.setEstado(0);
                    for( Cheque cheque : bolsaCliente.getChequeList() ){
                        cheque.setCodigoString( cheque.getCodigoString()+"E" );
                        cheque.setEstado(0);
                    }
                 }
                
                /* HACEMOS UN MERGE DE deleteCliente*/
                 try{
			em.getTransaction().begin();
			em.merge(deleteCliente);
			em.getTransaction().commit();
			mensaje = "Se eliminó el cliente";
                    
                    }catch(Exception ex){
				em.getTransaction().rollback();
				log.error(ex.getMessage(),ex);
                    }
		
                return mensaje;
	}



    @Override
    public DefaultComboBoxModel combo() {
        Query query                 = em.createQuery("SELECT c FROM Cliente c WHERE c.estado = 1 ORDER BY c.nombre",Cliente.class);
        List<Cliente> clienteList   = query.getResultList();
        DefaultComboBoxModel model  = new DefaultComboBoxModel();
        model.addElement(new JComboBoxModel("0", "Seleccione"));
        for(Cliente cliente : clienteList){
            model.addElement(new JComboBoxModel(cliente.getId().toString(), cliente.getNombre()));
        }
        
        return model;
    }

    @Override
    public List<Object[]> getLastSaldoActualClientes() {
        
        if(!em.isOpen()){ em = JPAUtil.getEntityManager(); }
        
//        StringBuilder mySqlQuery = new StringBuilder();
//        mySqlQuery.append(" SELECT cs.id,cli.nombre,cs.saldo_actual FROM cliente_saldo cs ");
//        mySqlQuery.append(" INNER JOIN cliente cli " );
//        mySqlQuery.append(" ON cs.cliente_id = cli.id ");
//        mySqlQuery.append(" WHERE cli.estado = 1 ");
//        mySqlQuery.append(" GROUP BY cs.id , cli.nombre,cs.saldo_actual ");
//        mySqlQuery.append(" HAVING cs.id IN ((SELECT MAX(id) FROM cliente_saldo cs GROUP BY cs.cliente_id)) ");
//        mySqlQuery.append(" ORDER BY cli.nombre");     
        
//        SELECT cli.nombre,l.total_liquidacion,l.saldo_cliente, ROUND(l.total_liquidacion + (l.saldo_cliente * (-1)) ,2) as "total a cobrar" ,cs.saldo_actual
//        FROM liquidacion l 
//        INNER JOIN cliente_saldo cs
//        ON cs.cliente_id = l.cliente_id
//        INNER JOIN cliente cli
//        ON cli.id = l.cliente_id
//        WHERE l.id IN ((SELECT MAX(id) FROM liquidacion liq GROUP BY liq.cliente_id))
//        AND cs.id IN ((SELECT MAX(id) FROM cliente_saldo cs GROUP BY cs.cliente_id)) 
//        GROUP BY l.cliente_id,l.total_liquidacion,l.saldo_cliente, ROUND(l.total_liquidacion + (l.saldo_cliente * (-1)) ,2)
//        ORDER BY cli.nombre
        
        StringBuilder mySqlQuery = new StringBuilder();
        mySqlQuery.append(" SELECT cli.nombre,l.total_liquidacion,l.saldo_cliente, ROUND(l.total_liquidacion + (l.saldo_cliente * (-1)) ,2) ,cs.saldo_actual ");
        mySqlQuery.append(" FROM liquidacion l ");
        mySqlQuery.append(" INNER JOIN cliente_saldo cs ");
        mySqlQuery.append(" ON cs.cliente_id = l.cliente_id ");
        mySqlQuery.append(" INNER JOIN cliente cli ");
        mySqlQuery.append(" ON cli.id = l.cliente_id ");
        mySqlQuery.append(" WHERE l.id IN ((SELECT MAX(id) FROM liquidacion liq GROUP BY liq.cliente_id)) ");
        mySqlQuery.append(" AND cs.id IN ((SELECT MAX(id) FROM cliente_saldo cs GROUP BY cs.cliente_id)) ");
        mySqlQuery.append(" GROUP BY l.cliente_id,l.total_liquidacion,l.saldo_cliente, ROUND(l.total_liquidacion + (l.saldo_cliente * (-1)) ,2) ");
        mySqlQuery.append(" ORDER BY cli.nombre ");
        
        
        
        Query query = em.createNativeQuery( mySqlQuery.toString() );
        
        List<Object[]> results = query.getResultList();
        return results;  
        
    }

	
	

}
